﻿using System;
using System.Activities;
using System.Threading.Tasks;

namespace MvcFlow.Execution
{
    internal static class WorkflowApplicationExtensions
    {
        internal static Task CancelAsync(this WorkflowApplication application)
        {
            return Task.Factory.FromAsync(application.BeginCancel, application.EndCancel, null);
        }

        internal static Task LoadAsync(this WorkflowApplication application, Guid instanceId)
        {
            return Task.Factory.FromAsync(application.BeginLoad, application.EndLoad, instanceId, null);
        }

        internal static Task PersistAsync(this WorkflowApplication application)
        {
            return Task.Factory.FromAsync(application.BeginPersist, application.EndPersist, null);
        }

        internal static Task RunAsync(this WorkflowApplication application)
        {
            return Task.Factory.FromAsync(application.BeginRun, application.EndRun, null);
        }

        internal static Task TerminateAsync(this WorkflowApplication application, Exception exception)
        {
            return Task.Factory.FromAsync(application.BeginTerminate, application.EndTerminate, exception, null);
        }

        internal static Task<BookmarkResumptionResult> ResumeBookmarkAsync(this WorkflowApplication application, Bookmark bookmark, object value)
        {
            return Task.Factory.FromAsync<Bookmark, object, BookmarkResumptionResult>(application.BeginResumeBookmark, application.EndResumeBookmark, bookmark, value, null);
        }

        internal static Task UnloadAsync(this WorkflowApplication application)
        {
            return Task.Factory.FromAsync(application.BeginUnload, application.EndUnload, null);
        }

        internal static async Task UnloadAndWaitAsync(this WorkflowApplication application)
        {
            var completionSource = new TaskCompletionSource<bool>();

            Action<WorkflowApplicationEventArgs> unloadedHandler = args => completionSource.SetResult(true);
            application.Unloaded += unloadedHandler;

            await application.UnloadAsync();
            await completionSource.Task;

            application.Unloaded -= unloadedHandler;
        }
    }
}